home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / GRAPHICS.SWG / 0140_Gouraud Shading.pas < prev    next >
Pascal/Delphi Source File  |  1995-03-03  |  6KB  |  176 lines

  1. {
  2. Here is the GOURAUD shading include file that came with Surface Modeler 3.0:
  3. }
  4. procedure GOURAUD;
  5. { Make a surface model drawing of the object with Gouraud interpolation
  6.   of surface shading }
  7.  
  8. var Node:                      word;          { node # }
  9.     Surf:                      word;          { surface # }
  10.     Shade:                     real;          { shade of surface }
  11.     Shade2:                    real;          { shade of 2nd side of surface }
  12.     Vert:                      integer;       { vertex # }
  13.     Interp:                    boolean;       { flag interpolated shading }
  14.     User_abort:                boolean;       { did the user abort? }
  15.     ch:                        char;
  16. {$ifndef BIGMEM}
  17.     Shades: nodearray;
  18.       { shade at each node }
  19.     Surfmin, Surfmax: surfaces;
  20.       { surface minimum & maximum (Ztran) }
  21.     Nshades: array[1..MAXNODES] of integer;
  22.       { # shades to average per node }
  23.     Sshade: surfaces;
  24.       { shade at each surface }
  25. {$endif}
  26. label ABORTTEXT,                              { text-mode abort }
  27.       ABORTGRPH;                              { graphics-mode abort }
  28.  
  29. begin
  30. {$ifdef BIGMEM}
  31. with ptrh^ do with ptri^ do with ptrj^ do
  32. with ptra^ do with ptrb^ do with ptrc^ do
  33. with ptrd^ do with ptre^ do with ptrf^ do
  34. with ptrh^ do with ptri^ do with ptrj^ do
  35. with ptrk^ do with ptrl^ do with ptrm^ do with ptrn^ do
  36. begin
  37. {$endif}
  38.  
  39.   perf_start;
  40.   User_abort := TRUE;
  41.   if (checkey) then goto ABORTTEXT;
  42. {$ifndef NOSHADOW}
  43.   if (Shadowing) then begin
  44.     shadows (Shades);
  45.     for Node := 1 to Nnodes do
  46.       Nshades[Node] := 0;
  47.   end else
  48. {$else}
  49.   if (Shadowing) then
  50.     writeln ('Error: Shadows not implemented in this version')
  51.   else
  52. {$endif}
  53.     for Node := 1 to Nnodes do begin
  54.       Shades[Node] := 0.0;
  55.       Nshades[Node] := 0;
  56.     end;
  57.  
  58.   if (Viewchanged) or (Shadowing) then begin
  59.     if (checkey) then goto ABORTTEXT;
  60.     menumsg ('Transforming to 2-D...');
  61. { Transform from 3-D to 2-D coordinates }
  62.     setorigin;
  63.     for Node := 1 to Nnodes do
  64.       perspect (Xworld[Node], Yworld[Node], Zworld[Node],
  65.                 Xtran[Node],  Ytran[Node],  Ztran[Node]);
  66.  
  67. { Set plotting limits and normalize transformed coords to screen coords }
  68.     perspect (Xfocal, Yfocal, Zfocal, Xfotran, Yfotran, Zfotran);
  69.     if (not setnormal (Xfotran, Yfotran, XYmax)) then begin
  70.       menumsg ('Warning: Focal point outside data limits.');
  71.       writeln;
  72.       write   ('  Press any key ...');
  73.       ch := readkey;
  74.     { Erase the previous message }
  75.       menumsg ('');
  76.       writeln;
  77.       write ('                          ');
  78.     end;
  79.  
  80.     if (checkey) then goto ABORTTEXT;
  81. { Normalize all the nodes }
  82.     for Node := 1 to Nnodes do
  83.       normalize (Xtran[Node], Ytran[Node], Xfotran, Yfotran, XYmax);
  84.     { Initialize all nodal shades to zero }
  85.  
  86.     if (checkey) then goto ABORTTEXT;
  87.     menumsg ('Sorting surfaces...');
  88.     minmax (Surfmin, Surfmax, Nsurf);
  89.     shelsurf (Surfmin, Surfmax, Nsurf);
  90.     Viewchanged := FALSE;
  91.   end; { if Viewchanged }
  92.  
  93.   setshade;                            { Setup for shading calculations }
  94.  
  95. { Compute the cumulative shading at every node (sum the shades due to
  96.   all surrounding surfaces) }
  97.   if (checkey) then goto ABORTTEXT;
  98.   menumsg ('Computing shades...');
  99.   for Surf := 1 to Nsurf do begin
  100.     if (Nsides = 2) then begin
  101.       { Use only the side of the surface with the brightest shade }
  102.       Shade := Shading (Surf, 1);
  103.       Shade2 := Shading (Surf, 2);
  104.       if (Shade2 > Shade) then
  105.         Shade := Shade2;
  106.     end else
  107.       Shade := Shading (Surf, 1);
  108.     { Surface shade }
  109.     Sshade[Surf] := Shade;
  110.     { Nodal shade }
  111.     for Vert := 1 to Nvert[Surf] do begin
  112.       Node := konnec (Surf, Vert);
  113.       if (Shade >= 0.0) and (Shades[Node] >= 0.0) then begin
  114.         Shades[Node] := Shades[Node] + Shade;
  115.         Nshades[Node] := Nshades[Node] + 1;
  116.       end;
  117.     end; { for Vert }
  118.   end; { for Surf }
  119.  
  120.   if (checkey) then goto ABORTTEXT;
  121. { Now average out the nodal shading }
  122.   for Node := 1 to Nnodes do
  123.     if (Nshades[Node] > 0) then
  124.       Shades[Node] := Shades[Node] / Nshades[Node];
  125.  
  126. {$ifdef USE_IFF}
  127.   menumsg ('Plotting...');
  128. {$endif}
  129.  
  130. { Now plot all the surfaces, with Gouraud shading }
  131.   setgmode (Nmatl);
  132.   for Surf := 1 to Nsurf do begin
  133.     if (Sshade[Surf] >= 0.0) then begin
  134.       Interp := TRUE;
  135.       { If any nodal shade varies from the average (surface) shade by more
  136.         than Epsilon, then don't use interpolated shading (unless the node
  137.         is in a shadow, in which case you should interpolate anyway) }
  138.       for Vert := 1 to Nvert[Surf] do begin
  139.         Node := konnec (Surf, Vert);
  140.         if (abs(Shades[Node] - Sshade[Surf]) > Epsilon) and
  141.            (Shades[Node] >= 0.0) then
  142.           Interp := FALSE;
  143.       end;
  144.       if (Interp) then
  145.         intrfill (Surf, Matl[Surf], Shades)
  146.       else
  147.         fillsurf (Surf, Matl[Surf], Sshade[Surf]);
  148.       { Show border of surface, if requested }
  149.       if (ShowAllBorders > 0) then
  150.         border (Surf, Matl[Surf]);
  151.     end; { if Sshade }
  152.     if (grafstat) then goto ABORTGRPH;
  153.   end; { for Surf }
  154.   drawaxes (Xfotran, Yfotran, XYmax);
  155.  
  156.   perf_stop (5);
  157.  
  158. {$ifdef USE_IFF}
  159.   menumsg ('Saving IFF...');
  160.   saveiff (Filemask + '.IFF', VGApal);
  161. {$else}
  162.   { Wait for user keypress to continue }
  163.   continue;
  164. {$endif}
  165.   User_abort := FALSE;
  166.  
  167.   ABORTGRPH:
  168.   exgraphic;
  169.   ABORTTEXT:
  170.   if (User_abort) then
  171.     perf_stop (0);
  172. {$ifdef BIGMEM}
  173. end; {with}
  174. {$endif}
  175. end; {procedure GOURAUD }
  176.